package com.chenl.provider.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.chenl.provider.DTO.ExcelInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

@Slf4j
public class EasyExcelUtils {
   /* @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public class ExcelInfo {

        private String name;

        private List<List<String>> headerList;

        private List<List<Object>> bodyList;
    }*/
    /**
     * 根据excelInfo集合导出文件,多个表格导入到同一个文件中
     *
     * @param file          file文件路径
     * @param excelName     表格名称
     * @param excelInfoList 封装好的ExcelInfoList对象
     */
    public static void exportList(File file, String excelName, List<ExcelInfo> excelInfoList) {
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteCellStyle.setWriteFont(headWriteFont);
        //若excelInfoList.size() > 1 代表包含多个sheet,多个sheet导入到同一个文件
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(file + "//" + excelName + ".xlsx").build();
            int count = 0;
            for (ExcelInfo excelInfo : excelInfoList) {
                WriteSheet sheet = EasyExcel.writerSheet(count, excelInfo.getSheetName()).registerWriteHandler(mergeStrategy()).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle,headWriteCellStyle)).head(excelInfo.getHeaderList()).build();
                excelWriter.write(excelInfo.getBodyList(), sheet);
                count++;
            }
        } catch (Exception e) {
            log.error("导出文件异常:{}", e.toString());
            throw new RuntimeException(e);
        } finally {
            excelWriter.finish();
        }
    }

    /**
     * 下载模板
     *
     * @param business 业务名称
     * @throws IOException e
     */
    public static void downloadExcelTemplate(String business) throws IOException {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        ExcelTemplateEnums template = ExcelTemplateEnums.getTemplate(business);
        InputStream in = null;
        OutputStream outputStream = null;
        try {
            // 设置导出文件名(PS:防止中文乱码)
            String downloadName = URLEncoder.encode(template.getDownloadName(), "UTF-8").replaceAll("\\+", "%20");
            // 读取项目excel模板流
//            in = EasyExcelUtils.class.getResourceAsStream("/template/" + template.getFileName() + ".xlsx");
            in = new ClassPathResource("/template/" + template.getFileName() + ".xlsx").getInputStream();
            // 设置response响应信息
            //response.setContentType("application/octet-stream;charset=UTF-8");//表示返回的数据是二进制流文件,它被用于传输文件数据，常用于文件下载功能
            response.setContentType("application/vnd.ms-excel");//表示返回的数据是Excel文件,告诉浏览器以Excel格式打开数据，让用户可以直接下载或查看Excel文件
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + downloadName + ".xlsx");
            response.addHeader("Access-Control-Expose-Headers", "name");
            response.setHeader("name", downloadName + ".xlsx");
            outputStream = response.getOutputStream();
            int readSize;
            byte[] buff = new byte[1024];
            while ((readSize = in.read(buff)) > -1) {
                outputStream.write(buff, 0, readSize);
            }
            outputStream.flush();
        } finally {
            if (in != null) {
                in.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    public static AbstractMergeStrategy mergeStrategy() {
        // 自定义单元格合并策略
        return null;
//        return new ColumnMergeStrategy(0, 2);
    }

    /**
     *
     * @param excelName:文件名称
     * @param excelInfoList:封装好的对象
     * @throws UnsupportedEncodingException
     */
    public static void exportListOut(String excelName, List<ExcelInfo> excelInfoList) throws UnsupportedEncodingException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = requestAttributes.getResponse();
        String fileName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\\+", "%20");
        //response.setContentType("application/octet-stream;charset=UTF-8");//表示返回的数据是二进制流文件,它被用于传输文件数据，常用于文件下载功能
        response.setContentType("application/vnd.ms-excel");//表示返回的数据是Excel文件,告诉浏览器以Excel格式打开数据，让用户可以直接下载或查看Excel文件
        response.addHeader("Access-Control-Expose-Headers", "name");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        response.setHeader("name", fileName + ".xlsx");
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteCellStyle.setWriteFont(headWriteFont);
        //若excelInfoList.size() > 1 代表包含多个sheet,多个sheet导入到同一个文件
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(response.getOutputStream()).build();
            int count = 0;
            for (ExcelInfo excelInfo : excelInfoList) {
                WriteSheet sheet = EasyExcel.writerSheet(count, excelInfo.getSheetName()).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle,headWriteCellStyle)).head(excelInfo.getHeaderList()).build();
                excelWriter.write(excelInfo.getBodyList(), sheet);
                count++;
            }
        } catch (Exception e) {
            log.error("导出文件异常:{}", e.toString());
            throw new RuntimeException(e);
        } finally {
            excelWriter.finish();
        }
    }

    /**
     *
     * @param excelName:文件名称
     * @param excelInfoList:封装好的对象
     * @throws UnsupportedEncodingException
     */
//    public static void exportListOutNew(String excelName, List<ExcelInfo> excelInfoList) throws UnsupportedEncodingException {
//        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletResponse response = requestAttributes.getResponse();
//        response.setContentType("application/vnd.ms-excel");
//        response.addHeader("Access-Control-Expose-Headers", "name");
//        response.setCharacterEncoding("utf-8");
//        String fileName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\\+", "%20");
//        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
//        response.setHeader("name", fileName + ".xlsx");
//        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
//        WriteFont headWriteFont = new WriteFont();
//        headWriteFont.setFontHeightInPoints((short) 12);
//        headWriteCellStyle.setWriteFont(headWriteFont);
//        //若excelInfoList.size() > 1 代表包含多个sheet,多个sheet导入到同一个文件
//        ExcelWriter excelWriter = null;
//        try {
//            excelWriter = EasyExcel.write(response.getOutputStream()).build();
//            int count = 0;
//            for (ExcelInfo excelInfo : excelInfoList) {
//                WriteSheet sheet = EasyExcel.writerSheet(count, excelInfo.getSheetName()).registerWriteHandler(new AbstractColumnWidthStyleStrategy() {
//                    @Override
//                    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
//                        Sheet sheet = writeSheetHolder.getSheet();
//                        int columnIndex = cell.getColumnIndex();
//                        //设置列宽(多列可以使用switch定制化)
//                        switch (columnIndex){
//                            case 0:
//                                sheet.setColumnWidth(columnIndex, 10000);
//                                break;
//                            case 1:
//                                sheet.setColumnWidth(columnIndex, 4000);
//                                break;
//                            case 2:
//                                sheet.setColumnWidth(columnIndex, 5500);
//                                break;
//                            case 3:
//                                sheet.setColumnWidth(columnIndex, 4000);
//                                break;
//                            case 4:
//                                sheet.setColumnWidth(columnIndex, 3500);
//                                break;
//                        }
//                        //设置行高
//                        sheet.setDefaultRowHeight((short) 350);
//                    }
//                }).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle,headWriteCellStyle)).head(excelInfo.getHeaderList()).build();
//                excelWriter.write(excelInfo.getBodyList(), sheet);
//                count++;
//            }
//        } catch (Exception e) {
//            log.error("导出文件异常:{}", e.toString());
//            throw new RuntimeException(e);
//        } finally {
//            excelWriter.finish();
//        }
//    }

    /**
     *
     * @param bodyList:body表格内容
     * @param excelName:表格名称
     * @param sheetName:sheet名称
     * @param clazz:导入类的clazz
     * @throws UnsupportedEncodingException
     */
    public static void exportListOutByObj(List<? extends Object> bodyList, String excelName, String sheetName, Class<? extends Object> clazz) throws UnsupportedEncodingException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = requestAttributes.getResponse();
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Access-Control-Expose-Headers", "name");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        response.setHeader("name", fileName + ".xlsx");
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteCellStyle.setWriteFont(headWriteFont);
        //若excelInfoList.size() > 1 代表包含多个sheet,多个sheet导入到同一个文件
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet sheet = EasyExcel.writerSheet(0, sheetName).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle,headWriteCellStyle)).head(clazz).build();
            excelWriter.write(bodyList, sheet);
        } catch (Exception e) {
            log.error("导出文件异常:{}", e.toString());
            throw new RuntimeException(e);
        } finally {
            excelWriter.finish();
        }
    }
}
